package main

import "fmt"

/**
鸭子类型(duck typing)：是动态类型的一种风格,
	不管对象属于哪个,也不管声明的具体接口是什么,
	只要对象实现了相应的方法,函数就可以在对象上执行操作.
即忽略对象的真正类型，转而关注对象有没有实现所需的方法、签名和语义.

interface 高内聚低耦合  通用万能类型 接口的特性是golang支持鸭子类型的基础
	在go中某个类型实现接口的函数,是没有感知的,与JAVA不同 JAVA实现接口后需要显式实现,
1.interface[] 空接口  int,stirng float32 float64 struct..都实现了interface[]
	就可以用interface[]类型 引用任意的数据类型
2.如某个struct 实现了函数与两个接口的函数都相同,那么这个struct对两个接口的函数都实现了,
3.接口像是一个公司利面的领导,他会定义一些通用规范,只涉及规范,尔不实现规范.
4.go语言的接口,是一种新的类型定义,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口
语法格式和方法非常类似

type interface_name interface{
	method_name1{return_type}
	method_name2{return_type}
	method_name3{return_type}
	.....
}
*/

// interface{}是万能数据类型
func myFunc(arg interface{}) {
	fmt.Println("myFunc...")
	fmt.Println(arg)

	// interface{} 改如何去区分此时引用的数据类型到底是谁
	// ## 给interface{} 提供了"断言"的机制
	value, ok := arg.(string)
	if !ok {
		fmt.Printf("arg is not string \n")
	} else {
		fmt.Printf("arg is %T %v \n", value, value)
	}

}

type USB interface {
	read()
	write()
}

type USB1 interface {
	read()
	write()
	// 只要有一个没有实现就会报错
	test()
}

// PC 两个接口函数相同 那么USB、USB1两个接口都实现了
type Camera struct {
	name string
}

func (c Camera) read() {
	fmt.Printf(" %v Camera read.... \n", c.name)
}

func (c Camera) write() {
	fmt.Printf(" %v Camera write.... \n", c.name)
}

type Android struct {
	name string
}

func (a Android) read() {
	fmt.Printf(" %v Android read.... \n", a.name)

}

func (a Android) write() {

	fmt.Printf(" %v Android write.... \n", a.name)
}

type Computer struct {
}

// 接收一个Usb接口类型的变量
// 只要是实现了USB接口
func (computer Computer) working(usb USB) {
	usb.read()
	usb.write()

}

func main() {
	computer := Computer{}

	camera := Camera{
		"康佳"}
	// 万能接口
	myFunc(camera)
	myFunc("123")
	computer.working(camera)

	android := Android{
		"OS"}
	computer.working(android)

}
